package com.gatesim;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Vector;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.Log;

public class Wire{
	
	//The output of a gate/volt
	private OutputConnection source;
	private InputConnection dest;
	private Gate gateSource;
	private Gate gateDest;
	private Paint paint;
	public boolean complete;
    public Vector<Point> pointVector;
    public int id;
    public static int wireId = 0;
    
    public Integer personalDelay;
    protected final int delayValue = 1;
    public int _gCount = 0;

	public Wire(OutputConnection s, InputConnection d, Gate gSource, Gate gDest){
		source = s;
		dest = d;
		gateSource = gSource;
		gateDest = gDest;
		complete = false;
		pointVector = new Vector<Point>();
		paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(3);
		
		id = wireId;
		wireId++;
		
		personalDelay = new Integer(0);
	}
	
	public void addLineEndOfPointVector(float x1, float y1) {
    	
    	this.pointVector.add(new Point((int)x1, (int)y1));
	}
	
	public void addLineBegOfPointVector(float x1, float y1){
	
		this.pointVector.add(0, new Point((int)x1, (int)y1));
	}
	
	public OutputConnection getSource(){
		return source;
	}
	
	public void setSource(OutputConnection oc){
		source = oc;
	}
	
	public InputConnection getDest(){
		return dest;
	}
	
	public void setDest(InputConnection ic){
		dest = ic;
	}
	
	public Gate getGateSource(){
		return gateSource;
	}
	
	public void setGateSource(Gate s){
		gateSource = s;
	}
	
	public Gate getGateDest(){
		return gateDest;
	}
	
	public void setGateDest(Gate d){
		gateDest = d;
	}
	
	public void relayCharge(){
		//set the dest pin to the same charge
		//as the source pin
		dest.setCharge(source.getCharge());
	}
	
	public int produceOut(){
	    gateSource.produceOut();
	    
	    if(GateWorld.animationMode){
	    	personalDelay = new Integer(gateSource.personalDelay + delayValue);
	    }
        if ( _gCount == personalDelay.intValue() ) { //i.intValue() ){
            Log.d("AnimateTimer", "ORGATE: _gCount: " + _gCount);
            
            if (source.getCharge() > 0 ) paint.setColor(Color.YELLOW);
            if (source.getCharge() <= 0 ) paint.setColor(Color.BLUE);
            
            _gCount = 0;
        }
	    
	    _gCount ++;
		//return dest.getCharge();
	    return 0;
	}
	
	public void completeWireSource(Gate g){
		this.setSource(g.fntPin);
		this.setGateSource(g);
		completeWire();
	}
	
	public void completeWireDest(Gate g, InputConnection ic){
		this.setDest(ic);
		this.setGateDest(g);
		completeWire();
	}
	
	//Completes the wire: the connections are now occupied!
	public void completeWire(){
		complete = true;
		if(source != null){
			source.occupy();
		}
		if(dest != null){
			dest.occupy();
		}
	}
	
	public void draw(Canvas c,Resources r, boolean simulationMode) {
        if ( !simulationMode ){
            paint.setColor(Color.RED);
            _gCount = 0;
        }
        
        
		if(complete){
			for(int i = 0; i < pointVector.size() - 1 ; i++){
			    c.drawLine(pointVector.get(i).x, pointVector.get(i).y,
			                    pointVector.get(i+1).x, pointVector.get(i+1).y, paint);
			}
		}
	}
	
	/*** To allow for gate movement... ***/
	public void pullPoint(int xDir, int yDir, Point p, int index){
	    double targetVectorAngle = Math.atan( yDir / xDir ) ;
	    double targetMagnitude = Math.sqrt( xDir * xDir + yDir * yDir );
	    
	    int yDist = pointVector.get(index).y - pointVector.get(index - 1).y;
	    int xDist = pointVector.get(index).x - pointVector.get(index - 1).x;
	    double vectorAngle = Math.atan( yDist / xDist ); // check if radians
	    
	    if (  Math.abs( targetVectorAngle - vectorAngle) > 5 ){
	        rotateWSClock( pointVector.get(index-1), pointVector.get(index), 5 );
	    }
	    
	}
	public void rotateWSClock(Point pivot, Point hand, double amount){
	    int xDist = hand.x - pivot.x;
	    int yDist = hand.y - pivot.y;
	    double radius = Math.sqrt( xDist * xDist + yDist * yDist );
	    double angle = Math.atan( yDist / xDist ); // check if radians
	    
	    double newAngle = angle + amount;
	    double newX = Math.cos(newAngle) * radius;
	    double newY = Math.sin(newAngle) * radius;
	    
	    hand.set((int)newX, (int)newY);
	}
	
}